package edu.hda.pt.client.connections;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import edu.hda.pt.client.PTClient;
import edu.hda.pt.client.connections.rmi.RMICallbackStreamHandler;
import edu.hda.pt.utils.Stream;
import edu.hda.pt.utils.TestObject;
import edu.hda.pt.utils.Stream.StreamState;
import edu.hda.pt.utils.connections.rmi.PTServerRMII;

/**
 * Client implementation for the connection method Java RMI
 * 
 * @author Marc Hammerton
 * 
 */
public class PTClientRMI extends PTClient {

	private PTServerRMII server;
	private String serverIP;

	RMICallbackStreamHandler handler;
	private Stream stream = null;

	/**
	 * Constructor for setting up the RMI client.
	 * 
	 * @param serverIP
	 *            - The IP address of the RMI server
	 */
	public PTClientRMI(String serverIP) {
		this.serverIP = serverIP;
	}

	/**
	 * @see edu.hda.pt.client.PTClient#connect()
	 */
	@Override
	public void connect() {
		Registry registry;
		try {
			registry = LocateRegistry.getRegistry(this.serverIP);
			server = (PTServerRMII) registry.lookup("PTServerRMI");
		} catch (RemoteException e) {
			System.out.println(this.clientID + "RemoteException: ");
			e.printStackTrace();
		} catch (NotBoundException e) {
			System.out.println(this.clientID + "NotBoundException: ");
			e.printStackTrace();
		}
	}

	/**
	 * @see edu.hda.pt.client.PTClient#disconnect()
	 */
	@Override
	public void disconnect() {

	}

	/**
	 * @see edu.hda.pt.client.PTClient#sendBool(boolean)
	 */
	@Override
	protected void sendBool(int messageId, boolean boolPrim) {
		try {
			@SuppressWarnings("unused")
			boolean response = server.getBool(boolPrim);
		} catch (RemoteException e) {
			System.out.println(this.clientID + "RemoteException: ");
			e.printStackTrace();
		}
	}

	/**
	 * @see edu.hda.pt.client.PTClient#sendBytes(byte[])
	 */
	@Override
	protected void sendBytes(int messageId, byte[] bytes) {
		try {
			@SuppressWarnings("unused")
			byte[] response = server.getBytes(bytes);
		} catch (RemoteException e) {
			System.out.println(this.clientID + "RemoteException: ");
			e.printStackTrace();
		}
	}

	/**
	 * @see edu.hda.pt.client.PTClient#sendInt(int)
	 */
	@Override
	protected void sendInt(int messageId, int intPrim) {
		try {
			@SuppressWarnings("unused")
			int response = server.getInteger(intPrim);
		} catch (RemoteException e) {
			System.out.println(this.clientID + "RemoteException: ");
			e.printStackTrace();
		}
	}

	/**
	 * @see edu.hda.pt.client.PTClient#sendLong(long)
	 */
	@Override
	protected void sendLong(int messageId, long longPrim) {
		try {
			@SuppressWarnings("unused")
			long response = server.getLong(longPrim);
		} catch (RemoteException e) {
			System.out.println(this.clientID + "RemoteException: ");
			e.printStackTrace();
		}
	}

	/**
	 * @see edu.hda.pt.client.PTClient#sendObject(edu.hda.pt.utils.TestObject)
	 */
	@Override
	protected void sendObject(int messageId, TestObject testObject) {
		try {
			@SuppressWarnings("unused")
			TestObject response = server.getObject(testObject);
		} catch (RemoteException e) {
			System.out.println(this.clientID + "RemoteException: ");
			e.printStackTrace();
		}
	}

	/**
	 * @see edu.hda.pt.client.PTClient#sendString(java.lang.String)
	 */
	@Override
	protected void sendString(int messageId, String text) {
		try {
			@SuppressWarnings("unused")
			String response = server.getString(text);
		} catch (RemoteException e) {
			System.out.println(this.clientID + "RemoteException: ");
			e.printStackTrace();
		}
	}

	/**
	 * @see edu.hda.pt.client.PTClient#sendStreamingRequest(int, int)
	 */
	@Override
	protected void sendStreamingRequest(int fs) {
		System.out.println(this.clientID + ": requesting stream");
		stream = new Stream(fs);
		stream.setState(StreamState.START);
		try {
			handler = new RMICallbackStreamHandler(this);
			stream = server.handleStream(stream, handler);
		} catch (RemoteException e) {
			e.printStackTrace();
		}

	}

	/**
	 * @see edu.hda.pt.client.PTClient#terminateStreaming()
	 */
	@Override
	protected void terminateStreaming() {
		if (stream != null && stream.getState() == StreamState.RUNNING) {
			stream.setState(StreamState.FINISH);
			try {
				stream = server.handleStream(stream, handler);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
			System.out.println(this.clientID + ": stopping stream");
		}
	}

}
